<html>
<!--
This HTML file is the swingp visualizer.

The basic architecture is based on a cooperative multithreading model, with the two functional units as follows:
1) An HTTP long-poller that polls Studio for swingp render stats.
    * Each fetch may return one or more swingp frame renders containing multiple threads.
    * The data is encoded via a simple bytes_length + content_bytes[bytes_length] encoding.
    * Each content_bytes[bytes_length] is a complete JSON tree structure, in the pattern of [ThreadStat+].
    * During processing of each ThreadStat, rectangles are generated for rendered components' bounds, and frame bounds are (perhaps) updated.
2) A render loop that takes the rectangles and bounds generated/updated in the poller functional unit, and renders them to the canvas.
    * The canvas is hardcoded to render at 1/4 of Swing's resolution.
    * The 1/4 resolution might not be suitable for high DPI displays -- one can change the frameScale and reload the page.
    * Each rectangle is re-rendered according to a time-based alpha decay.
    * Rectangles' alpha are tied to the parent JSON render tree's lifetime (so all rectangles generated by a single JSON tree shares alpha).
    * Primary (main window) is rendered in green, and secondary (popups and other heavy weight components on top) are rendered in red.
-->

<head>
    <script type="text/javascript" src="Visualizer.js"></script>
    <script type="text/javascript" src="SwingPPoller.js"></script>
    <script type="text/javascript" src="FrameManager.js"></script>
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script type="text/javascript">
        var poller;
        var visualizer;
        window.onload = function () {
            poller = new SwingPPoller(false);
            visualizer = new Visualizer(document.getElementById("canvas"),
                document.getElementById("root_filter_element"),
                document.getElementById("components_rendered"));
            frameManager = new FrameManager(document.getElementById("perf_chart"), document.getElementById("frame_tree_canvas"));
            poller.addInputHandler(visualizer.processInput);
            poller.addInputHandler(frameManager.processInput);
            setInterval(() => {
                visualizer.draw();
                frameManager.draw();
            }, 17);
        }
        function resizeCanvas() {
            document.getElementById("canvas").width = window.innerWidth;
            document.getElementById("frame_tree_canvas").width = window.innerWidth;
        }
    </script>
</head>

<body onresize="resizeCanvas()">
<form>
    <fieldset>
        <legend>Render:</legend>
        Filter Root: <input type="text" id="root_filter_element" placeholder="e.g. SomeAwtOrSwingComponentType"><br>
        <p id="components_rendered"></p>
        <canvas id="canvas" />
    </fieldset>
    <fieldset>
        <legend>Frames:</legend>
        Cached Frames: <input type="range" min="10" max="250" value="75" class="slider" id="cahced_frames_element"
                              oninput="frameManager.setMaxFrames(this.value)" onchange="frameManager.setMaxFrames(this.value)"><br />
        Pause: <input type="checkbox" onclick="frameManager.togglePause()" />
        <div id="perf_chart"></div>
        <canvas id="frame_tree_canvas" />
    </fieldset>
</form>
</body>

</html>